/** Clase principal, que proporciona el menu para utilizar la aplicacion **/

package clientegestionred;

import common.Cons;
import common.SesionSNMP;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.UnknownHostException;


public class GestorDeRed implements Cons {

    private static String address; //direccion remota completa

    private static String remoteIP; //direccion ip remota

    private static String remotePort; //puerto remoto

    private static BufferedReader bReader; //lectura por teclado

    // Sesiones
    private static SesionSNMP sesionGet; //sesion para lectura
    private static SesionSNMP sesionSet; //sesion para escritura

    // Hilos
    private static GestorDeTraps gestor_traps; //espera por traps
    private static HiloConsultaUsoProcesador hilo_proc; //consultar sobrecarga


    /* Metodo principal de la aplicacion */
    public static void main(String[] args) {

        // Inicializar los atributos de conexion
        // en funcion del numero de argumentos introducidos
        compruebaArgs(args);
        address = remoteIP + "/" + remotePort;

        // Comprobar que la direccion introducida es un IP valida
        try{
            InetAddress ia = InetAddress.getByName(remoteIP);
        } catch (UnknownHostException e) {
            System.err.println("IP desconocida. El programa no puede continuar.");
            System.err.flush();
            System.exit(-1);
        }

        // Establecer las sesiones SNMP
        sesionGet = new SesionSNMP(address, R0_COMMUNITY);
        sesionSet = new SesionSNMP(address, RW_COMMUNITY);
        
        // Lanzar los hilos
        gestor_traps = new GestorDeTraps(sesionGet);
        gestor_traps.start(); //esperar por traps
        hilo_proc = new HiloConsultaUsoProcesador(sesionGet);
        hilo_proc.start(); //consultar sobrecarga

        // Mensaje de bienvenida
        System.out.println("Bienvenido al menú principal del GestorDeRed.\n");

        int tarea = 0;
        String index = null;
        bReader = new BufferedReader(new InputStreamReader(System.in));

        do{
            // Sacar por pantalla el menu principal y esperar eleccion
            imprimeMenu();

            // Procesar la eleccion comprobando errores
            try {
                index = bReader.readLine();
            } catch (IOException ex) {
                System.err.println("Error en la lectura por teclado. El"
                        + " programa finalizara.");
                System.err.println("Exception Message = " + ex.getMessage());
                //Cerrar todo salir
                terminaSesiones();
                terminaHilos();
                System.exit(-1);
            }

            try{
                tarea = Integer.parseInt(index.trim());
            }catch(java.lang.NumberFormatException ex){
                System.err.println("\tEl valor introducido es incorrecto. "
                        + "Por favor, introduzca un numero valido.\n");
                tarea = -1;
            }

            // Actuar en funcion de lo seleccionado por teclado
            llamaTarea(tarea);
            
        } while (tarea != 0);

        System.out.println("\nGracias por confiar en ClienteGestionRed para"
                + " administrar su red.\n");
        System.out.flush();

        // Cerrar los hilos
        terminaHilos();
        // Cerrar las sesiones
        terminaSesiones();

    } //main

    /* Metodo que inicializa remoteIP y remotePort en funcion
     de los argumentos pasados al programa */
    private static void compruebaArgs(String [] args){
        switch (args.length){
            case 0:
                remoteIP = "127.0.0.1";
                remotePort = "161";
                break;
            case 1:
                remoteIP = args[0];
                remotePort = "161";
                break;
            case 2:
                remoteIP = args[0];
                remotePort = args[1];
                break;
            default:
                System.err.println("Debe introducir como argumento la direccion"
                    + "IP del dispositivo a gestionar.");
                System.err.flush();
                throw (new RuntimeException ("Sintaxis: GestorDeRed <dir_remota> "
                    + "[puerto]"));
        } //switch
    } //compruebaARgs

    /* Imprimir el Menu principal de la aplicacion */
    private static void imprimeMenu() {
        System.out.println("\n------------------------------- MENU PRINCIPAL "
                    + "-------------------------------");
            System.out.println("  1.- Obtener informacion del sistema, y configurar"
                + " algunos de los parametros.");
            System.out.println("  2.- Visualizar informacion sobre las interfaces.");
            System.out.println("  3.- Observar el estado de las conexiones.");
            System.out.println("  4.- Comprobar la utilizacion de los recursos"
                    + " de almacenamiento.");
            System.out.println("  5.- Averiguar la carga de trabajo.");

            System.out.println("  0.- Salir.");
            System.out.println("---------------------------------------------"
                    + "---------------------------------");
            System.out.print("Indique la tarea que desea realizar: ");
            System.out.flush();
    } //imprimeMenu

    /* Hacer la tarea indicada en la eleccion por teclado */
    private static void llamaTarea(int tarea) {
        switch(tarea){
            case 1: //informacion del sistema
                InfoSistema is = new InfoSistema(sesionGet, sesionSet);
                is.getAndModify();
                break;

            case 2: //informacion de las interfaces
                InfoInterfaz ii = new InfoInterfaz(sesionGet);
                try {
                    ii.start();
                } catch (IOException ex) {
                    System.err.println("Exception Message = " + ex.getMessage());
                    //Cerrar todo y salir
                    terminaSesiones();
                    terminaHilos();
                    System.exit(-1);
                }
                break;

            case 3: //informacion TCP/UDP
                InfoTransporte it = new InfoTransporte(sesionSet);
                try {
                    it.start();
                } catch (IOException ex) {
                    //Cerrar todo y salir
                    terminaSesiones();
                    terminaHilos();
                    System.exit(-1);
                }
                break;

            case 4: //informacion de la memoria
                UsoMemoria um =  new UsoMemoria(sesionGet);
                um.getMemoryInfo();
                break;

            case 5: //informacion de la carga de trabajo
                UsoProcesador up = new UsoProcesador(sesionGet);
                up.getNumberOfProcesses();
                up.getProcessorLoad();
                break;

            case 0:
                break;

            default:
                if (tarea >= 0)
                    System.out.println("\tOpcion no valida. Seleccione un numero"
                        + " de los disponibles.\n");
                break;
        } //switch
    }
    
    /* Cerrar las sesiones */
    public static void terminaSesiones(){
        try {
            sesionGet.stop();
            sesionSet.stop();
        } catch (IOException ex) {}
    }

    /* Cerrar los hilos */
    public static void terminaHilos(){
        hilo_proc.setExit(true);
        hilo_proc.interrupt();
        gestor_traps.despierta();
    }

} //class
